﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Data;
using System.IO;
using System.Data.OleDb;
using DMS.BaseClass;
using ICSharpCode.SharpZipLib.Zip;

namespace DMS.Business.Utility
{
    public class ClientHelper
    {
        private static ClientHelper _helper = null;
        public static ClientHelper Instance
        {
            get
            {
                if (ClientHelper._helper == null)
                {
                    ClientHelper._helper = new ClientHelper();
                }
                return ClientHelper._helper;
            }
        }
        protected ClientHelper()
        {
        }

        private const string ScriptTemplate = "<script language=\"javascript\" type=\"text/javascript\">{0}</script>";

        public void Alert(string msg)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("alert('{0}');", msg);

            this.RenderScript(null, string.Empty, sb.ToString());
        }

        public void Alert(string msg,string script)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("alert('{0}');", msg);
            if (!string.IsNullOrEmpty(script))
                sb.Append(script);
            this.RenderScript(null, string.Empty, sb.ToString());
        }

        public void RenderScript(string script)
        {
            StringBuilder sb = new StringBuilder();
            if (!string.IsNullOrEmpty(script))
                sb.Append(script);
            this.RenderScript(null, string.Empty, sb.ToString());
        }

        public void RefreshPage()
        {
            this.RefreshPage(true);
        }

        public void RefreshPage(bool replace)
        {
            string script = string.Empty;
            if (replace)
            {
                script = "window.location.replace(window.location.href);";
            }
            else
            {
                script = "window.location = window.location.href;";
            }

            this.RenderScript(null, string.Empty, script);
        }

        public void CloseWindow()
        {
            this.CloseWindow(string.Empty, string.Empty, RefreshType.NoRefresh);
        }

        public void CloseWindow(string msg, string returnVal)
        {
            this.CloseWindow(msg, returnVal, RefreshType.NoRefresh);
        }

        public void CloseWindow(string msg, string returnVal, RefreshType refreshParent)
        {
            StringBuilder sb = new StringBuilder();
            if (!string.IsNullOrEmpty(msg))
            {
                sb.AppendFormat("alert('{0}');", msg);
            }

            if (refreshParent == RefreshType.OpenDialog)
            {
                if (returnVal == null)
                {
                    returnVal = string.Empty;
                }
                //returnVal += "#;Refresh:Reload#;";
            }
            else if (refreshParent == RefreshType.OpenWindow)
            {
                sb.Append("try{window.opener.location.reload(true);}catch(ex){}; window.open('','_self'); ");
            }
            else if (refreshParent == RefreshType.NoRefresh)
            {
                sb.Append("window.open('','_self'); ");
            }

            if (!string.IsNullOrEmpty(returnVal))
            {
                sb.AppendFormat("window.returnValue = \"{0}\";", returnVal);
            }

            sb.Append("window.close();");

            this.RenderScript(null, string.Empty, sb.ToString());
        }

        public void RenderScript(Page page, string scriptName, string content)
        {
            if (page == null)
            {
                page = HttpContext.Current.Handler as Page;
            }
            if (string.IsNullOrEmpty(scriptName))
            {
                scriptName = Guid.NewGuid().ToString();
            }

            try
            {
                page.ClientScript.RegisterStartupScript(typeof(Page), scriptName, string.Format(ScriptTemplate, content));
            }
            catch (Exception ex)
            {
                LogHelper.LogException(ex);
            }
        }

        public void SetReadOnlyStatue(Control ctrl, string action)
        {
            if (ctrl == null)
            {
                return;
            }
            IAttributeAccessor ctrl_att = ctrl as IAttributeAccessor;
            HtmlControl ctrl_html = ctrl as HtmlControl;
            WebControl ctrl_web = ctrl as WebControl;

            // ReadOnly
            if (!string.IsNullOrEmpty(ctrl_att.GetAttribute("CanModify")))
            {
                string canModify = ctrl_att.GetAttribute("CanModify").ToUpper();
                if (canModify.Contains(action.ToUpper()))
                {
                    if (ctrl_web != null)
                    {
                        if (ctrl_web is DropDownList)
                        {
                            ((DropDownList)ctrl_web).Enabled = true;
                        }
                        else
                        {
                            ctrl_web.Attributes.Remove("readOnly");
                        }
                    }
                    else if (ctrl_html != null)
                    {
                        ctrl_html.Attributes.Remove("readOnly");
                    }
                }
                else
                {
                    if (ctrl_web != null)
                    {
                        if (ctrl_web is DropDownList)
                        {
                            ((DropDownList)ctrl_web).Enabled = false;
                        }
                        else
                        {
                            ctrl_web.Attributes["readOnly"] = "true";
                        }
                    }
                    else if (ctrl_html != null)
                    {
                        ctrl_html.Attributes["readOnly"] = "true";
                    }
                }
            }
        }

        public void SetDisplayStatue(Control ctrl, string action)
        {
            if (ctrl == null)
            {
                return;
            }
            IAttributeAccessor ctrl_att = ctrl as IAttributeAccessor;
            HtmlControl ctrl_html = ctrl as HtmlControl;
            WebControl ctrl_web = ctrl as WebControl;

            // Visible
            if (!string.IsNullOrEmpty(ctrl_att.GetAttribute("CanDisplay")))
            {
                string canDisplay = ctrl_att.GetAttribute("CanDisplay").ToUpper();
                ctrl.Visible = canDisplay.Contains(action.ToUpper());
            }
        }

        public void ExportToExcel(DataTable dt, string fileName)
        {
            Encoding Encoding = Encoding.UTF8;
            StringWriter stringWriter = new StringWriter();
            HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);

            HttpResponse reponse = HttpContext.Current.Response;
            reponse.Clear();
            reponse.Write(string.Format("<meta http-equiv='Content-Type'; content='text/html';charset='{0}'>", Encoding.WebName));
            reponse.AddHeader("content-disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding) + ".xls");
            reponse.ContentType = "application/ms-excel";
            reponse.ContentEncoding = Encoding;
            reponse.Charset = Encoding.WebName;

            GridView list = new GridView();
            list.BorderWidth = 1;
            list.HeaderStyle.Font.Bold = true;

            list.AutoGenerateColumns = true;
            list.Caption = string.Format("<span style=\"font-weight:bold; font-size:22pt;\">{0} </span>", dt.TableName);
            list.DataSource = dt;
            list.DataBind();
            list.RenderControl(htmlWriter);

            reponse.Write(stringWriter.ToString());
            reponse.End();
        }

        public void ExportToExcel(DataGrid list, string fileName)
        {
            Encoding Encoding = Encoding.UTF8;
            StringWriter stringWriter = new StringWriter();
            HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);

            HttpResponse reponse = HttpContext.Current.Response;
            reponse.Clear();
            reponse.Write(string.Format("<meta http-equiv='Content-Type'; content='text/html';charset='{0}'>", Encoding.WebName));
            reponse.AddHeader("content-disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding) + ".xls");
            reponse.ContentType = "application/ms-excel";
            reponse.ContentEncoding = Encoding;
            reponse.Charset = Encoding.WebName;
            
            list.RenderControl(htmlWriter);

            reponse.Write(stringWriter.ToString());
            reponse.End();
        }

        public void ExportToExcel(GridView list, string fileName)
        {
            Encoding Encoding = Encoding.UTF8;
            StringWriter stringWriter = new StringWriter();
            HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);

            HttpResponse reponse = HttpContext.Current.Response;
            reponse.Clear();
            reponse.Write(string.Format("<meta http-equiv='Content-Type'; content='text/html';charset='{0}'>", Encoding.WebName));
            reponse.AddHeader("content-disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding) + ".xls");
            reponse.ContentType = "application/ms-excel";
            reponse.ContentEncoding = Encoding;
            reponse.Charset = Encoding.WebName;

            list.RenderControl(htmlWriter);

            reponse.Write(stringWriter.ToString());
            reponse.End();
        }

        public void ExportToExcelForMutilSheet1(DataTable[] dts, string fileName)
        {
            Encoding Encoding = Encoding.UTF8;

            HttpResponse response = HttpContext.Current.Response;
            response.ClearContent();
            response.BufferOutput = true;
            response.Charset = "utf-8";
            response.ContentType = "text/xml";
            response.ContentEncoding = System.Text.Encoding.UTF8;
            response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding) + ".xls");

            StringBuilder sbf = new StringBuilder();

            sbf.Append("<?xml version='1.0'?><?mso-application progid='Excel.Sheet'?>");
            sbf.Append(@"\r\n<Workbook xmlns='urn:schemas-microsoft-com:office:spreadsheet' 
                                xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel' 
                                xmlns:ss='urn:schemas-microsoft-com:office:spreadsheet' xmlns:html='http://www.w3.org/TR/REC-html40'>");
            sbf.Append(@"\r\n<DocumentProperties xmlns='urn:schemas-microsoft-com:office:office'>");
            sbf.Append(@"\r\n<Author>DMS</Author><LastAuthor>DMS</LastAuthor>");
            sbf.Append("\r\n</DocumentProperties>");
            sbf.Append(@"\r\n<Styles><Style ss:ID='Default' ss:Name='Normal'><Alignment ss:Vertical='Center'/>
                            <Borders/><Font ss:FontName='宋体' x:CharSet='134' ss:Size='12'/><Interior/><NumberFormat ss:Format='@'/><Protection/></Style>");
            //定义标题样式    
            sbf.Append(@"<Style ss:ID='Header'><Borders><Border ss:Position='Bottom' ss:LineStyle='Continuous' ss:Weight='1'/>
                            <Border ss:Position='Left' ss:LineStyle='Continuous' ss:Weight='1'/>
                            <Border ss:Position='Right' ss:LineStyle='Continuous' ss:Weight='1'/>
                            <Border ss:Position='Top' ss:LineStyle='Continuous' ss:Weight='1'/></Borders>
                            <Font ss:FontName='宋体' x:CharSet='134' ss:Size='18' ss:Color='#FF0000' ss:Bold='1'/></Style>");

            //定义边框
            sbf.Append(@"<Style ss:ID='border'><NumberFormat ss:Format='@'/><Borders>
                            <Border ss:Position='Bottom' ss:LineStyle='Continuous' ss:Weight='1'/>
                            <Border ss:Position='Left' ss:LineStyle='Continuous' ss:Weight='1'/>
                            <Border ss:Position='Right' ss:LineStyle='Continuous' ss:Weight='1'/>
                            <Border ss:Position='Top' ss:LineStyle='Continuous' ss:Weight='1'/></Borders></Style>");
            sbf.Append("</Styles>");

            foreach (DataTable dt in dts)
            {
                GridView list = new GridView();
                list.BorderWidth = 1;
                list.HeaderStyle.Font.Bold = true;

                list.AutoGenerateColumns = true;
                list.Caption = string.Format("<span style=\"font-weight:bold; font-size:22pt;\">{0} </span>", dt.TableName);
                list.DataSource = dt;
                list.DataBind();

                sbf.Append("\r\n<Worksheet ss:Name='" + dt.TableName + "'>");
                sbf.Append("\r\n<Table x:FullColumns='1' x:FullRows='1'>");
                //输出标题

                //计算该 Sheet 中的数据起始行和结束行。
                int start = 2;
                int end = list.Rows.Count;

                sbf.Append("\r\n<Row ss:AutoFitHeight='1'>");
                for (int j = 0; j < list.HeaderRow.Cells.Count; j++)
                {
                    sbf.Append("<Cell ss:StyleID='Header'><Data ss:Type='String'>" + list.HeaderRow.Cells[j].Text + "</Data></Cell>");
                }
                sbf.Append("\r\n</Row>");

                for (int j = start; j < end; j++)
                {
                    sbf.Append("\r\n<Row>");
                    for (int c = 0; c < list.HeaderRow.Cells.Count; c++)
                    {
                        //对于数字，采用Number数字类型
                        if (c > 1)
                        {
                            sbf.Append("<Cell ss:StyleID='border'><Data ss:Type='Number'>" + list.Rows[j].Cells[c].Text + "</Data></Cell>");
                        }
                        else
                        {
                            sbf.Append("<Cell ss:StyleID='border'><Data ss:Type='String'>" + list.Rows[j].Cells[c].Text + "</Data></Cell>");
                        }
                    }
                    sbf.Append("\r\n</Row>");
                }
                sbf.Append("\r\n</Table>");
                sbf.Append("\r\n</Worksheet>");

            }

            sbf.Append("\r\n</Workbook>");

            StringWriter stringWriter = new StringWriter();
            HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);

            stringWriter.Write(sbf.ToString());

            response.Write(stringWriter.ToString());

            response.End();
        }

        public void ExportToExcelForMutilSheet(List<DataTable> dtList, string fileName)
        {
            // 下面采用的是DataTable，也可以采用DataSet，其中每个DataTable可以保存成一个 Sheet
            // 迅雷下载时可以在下载完毕后会自动把文件名更新成 xls 或者 xml 的。
            HttpResponse Response = HttpContext.Current.Response;
            Encoding Encoding = Encoding.UTF8;

            Response.ClearContent();
            Response.BufferOutput = true;
            Response.Charset = "utf-8";
            Response.ContentType = "application/ms-excel";
            Response.AddHeader("Content-Transfer-Encoding", "binary");
            Response.ContentEncoding = System.Text.Encoding.UTF8;
            string headerName = fileName;
            fileName = HttpUtility.UrlEncode(fileName, Encoding);
            Response.AppendHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");
            Response.Write("<?xml version='1.0'?><?mso-application progid='Excel.Sheet'?>");
            Response.Write(@"<Workbook xmlns='urn:schemas-microsoft-com:office:spreadsheet'
      xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel'
      xmlns:ss='urn:schemas-microsoft-com:office:spreadsheet' xmlns:html='http://www.w3.org/TR/REC-html40'>");
            Response.Write(@"<DocumentProperties xmlns='urn:schemas-microsoft-com:office:office'>");
            Response.Write(@"<Author>DMS</Author><LastAuthor>DMS</LastAuthor>
          <Company>GZ-GMCC</Company><Version>1990</Version>");
            Response.Write("</DocumentProperties>");
            Response.Write(@"<Styles><Style ss:ID='Default' ss:Name='Normal'><Alignment ss:Vertical='Center'/>
      <Borders/><Font ss:FontName='宋体' x:CharSet='134' ss:Size='12'/><Interior/><NumberFormat ss:Format='@'/><Protection/></Style>");
            //定义标题样式    
            Response.Write(@"<Style ss:ID='Title'><Alignment ss:Horizontal='Center' ss:Vertical='Center'/>
       <Font ss:FontName='宋体' x:CharSet='134' ss:Size='14' ss:Color='#000000' ss:Bold='1'/></Style>");
            //定义统计信息样式    
            Response.Write(@"<Style ss:ID='StatisticInfo'>
       <Font ss:FontName='宋体' x:CharSet='134' ss:Size='12' ss:Color='#000000' ss:Bold='1'/></Style>");
            //定义表头样式   
            Response.Write(@"<Style ss:ID='Header'><Borders><Border ss:Position='Bottom' ss:LineStyle='Continuous' ss:Weight='1'/>
       <Border ss:Position='Left' ss:LineStyle='Continuous' ss:Weight='1'/>
       <Border ss:Position='Right' ss:LineStyle='Continuous' ss:Weight='1'/>
       <Border ss:Position='Top' ss:LineStyle='Continuous' ss:Weight='1'/></Borders><Alignment ss:Horizontal='Center' ss:Vertical='Center'/>
       <Font ss:FontName='宋体' x:CharSet='134' ss:Size='12' ss:Color='#000000' ss:Bold='1'/></Style>");

            //定义边框
            Response.Write(@"<Style ss:ID='border'><NumberFormat ss:Format='@'/><Borders>
      <Border ss:Position='Bottom' ss:LineStyle='Continuous' ss:Weight='1'/>
      <Border ss:Position='Left' ss:LineStyle='Continuous' ss:Weight='1'/>
      <Border ss:Position='Right' ss:LineStyle='Continuous' ss:Weight='1'/>
      <Border ss:Position='Top' ss:LineStyle='Continuous' ss:Weight='1'/></Borders></Style>");

            Response.Write("</Styles>");

            foreach (DataTable dt in dtList)
            {
                //Sheet 中的数据起始行和结束行。
                int start = 0;
                int end = dt.Rows.Count;

                Response.Write("<Worksheet ss:Name='" + dt.TableName + "'>");
                Response.Write("<Table x:FullColumns='1' x:FullRows='1'>");

                //输出标题
                Response.Write("\r\n<Row ss:AutoFitHeight='1'>");
                Response.Write("<Cell ss:StyleID='Title' ss:MergeAcross='" + (dt.Columns.Count - 1) + "'><Data ss:Type='String'>" + headerName + "</Data></Cell>");
                Response.Write("\r\n</Row>");

                //输出表头
                Response.Write("\r\n<Row ss:AutoFitHeight='1'>");
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    Response.Write("<Cell ss:StyleID='Header'><Data ss:Type='String'>" + dt.Columns[j].ColumnName + "</Data></Cell>");
                }
                Response.Write("\r\n</Row>");


                for (int j = start; j < end; j++)
                {
                    Response.Write("<Row ss:AutoFitWeight='1'>");
                    for (int c = 0; c < dt.Columns.Count; c++)
                    {
                        Response.Write("<Cell ss:StyleID='border'><Data ss:Type='String'>" + dt.Rows[j][c].ToString() + "</Data></Cell>");
                    }

                    Response.Write("</Row>");
                }
                Response.Write("</Table>");
                Response.Write("</Worksheet>");
                //Response.Flush();
            }
            Response.Write("</Workbook>");
            Response.End();
        }

        //从远程文件服务器（IIS的路径）下载文件
        public void DownloandFile(string fileName, string targetUrl, HttpResponse response)
        {
            Uri uri = new Uri(targetUrl);
            Stream fileStream = FileTruck.DownloadFile(uri.OriginalString);
            try
            {               
                int bufferSize = 2048;
                int readCount = 0;
                byte[] buffer = new byte[bufferSize];

                readCount = fileStream.Read(buffer, 0, bufferSize);
                while (readCount > 0)
                {

                    response.OutputStream.Write(buffer, 0, readCount);
                    readCount = fileStream.Read(buffer, 0, bufferSize);
                }
            }
            catch (Exception ex)
            {
                LogHelper.LogException(ex);
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Dispose();
                }
            }

        }

        /// <summary>
        /// 拷贝文件到本地
        /// </summary>
        /// <param name="fileUrl"></param>
        /// <param name="localFolder"></param>
        /// <returns>文件的相对路径</returns>
        public string CopyFileToLocal(string fileUrl, string localFolder)
        {
            Uri uri = new Uri(fileUrl);

            // 检查本地路径 
            string folder = "/Attachments/Temp";
            if (!string.IsNullOrEmpty(localFolder))
            {
                folder = localFolder;
            }

            // 获取参数
            string fileName = VirtualPathUtility.GetFileName(uri.AbsolutePath);
            string localFilePath_relative = string.Format("{0}/{1}", folder, fileName);
            string localFilePath_full = HttpContext.Current.Server.MapPath(localFilePath_relative);

            // 复制文件
            FileStream fs = null;
            Stream stExcel = null;
            try
            {
                fs = File.Create(localFilePath_full);
                stExcel = FileTruck.DownloadFile(uri.OriginalString);

                int bufferSize = 2048;
                int readCount = 0;
                byte[] buffer = new byte[bufferSize];

                readCount = stExcel.Read(buffer, 0, bufferSize);
                while (readCount > 0)
                {
                    fs.Write(buffer, 0, readCount);
                    readCount = stExcel.Read(buffer, 0, bufferSize);
                }
            }
            catch (Exception ex)
            {
                LogHelper.LogException(ex);
            }
            finally
            {
                if (fs != null)
                {
                    fs.Dispose();
                }
                if (stExcel != null)
                {
                    stExcel.Dispose();
                }
            }

            return localFilePath_relative;
        }

        /// <summary>
        /// 解压zip
        /// </summary>
        /// <param name="fullFilePath">文件全路径</param>
        /// <returns>返回文件夹全路径</returns>
        public string ExtractZip(string fullFilePath)
        {
            FileInfo fi = new FileInfo(fullFilePath);
            string folderPath = Path.Combine(fi.Directory.FullName, fi.Name.TrimEnd(fi.Extension.ToCharArray()));
            DirectoryInfo folder = new DirectoryInfo(folderPath);
            if (!folder.Exists)
                folder.Create();
            
            //string folder = string.Format("{0}_Content", zipPath.TrimEnd(".zip".ToCharArray()));
            
            Stream stream =  File.Open(fullFilePath,FileMode.Open);
            using (ZipInputStream zipStream = new ZipInputStream(stream))
            {
                ZipEntry entry = zipStream.GetNextEntry();
                while (entry != null)
                {
                    if (!entry.IsFile)
                    {
                        continue;
                    }

                    string filePath = Path.Combine(folder.FullName,entry.Name);

                    using (FileStream fs = File.Create(filePath))
                    {
                        int bufferSize = 2048; //缓冲区大小
                        int readCount = 0; //读入缓冲区的实际字节
                        byte[] buffer = new byte[bufferSize];
                        readCount = zipStream.Read(buffer, 0, bufferSize);
                        while (readCount > 0)
                        {
                            fs.Write(buffer, 0, readCount);
                            readCount = zipStream.Read(buffer, 0, bufferSize);
                        }
                    }
                    entry = zipStream.GetNextEntry();
                }
            }

            return folder.FullName;
        }

        public DataSet ExcelToDS(string filePath, string sheet)
        {
            DataSet ds = new DataSet();
            string sheetName = string.IsNullOrEmpty(sheet) ? "Sheet1" : sheet;
            string strExcel = string.Format("SELECT * FROM [{0}$]", sheetName);
            string strConn = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;IMEX=1'", filePath);
            OleDbConnection conn = new OleDbConnection(strConn);
            try
            {
                conn.Open();

                OleDbDataAdapter myCommand = null;

                myCommand = new OleDbDataAdapter(strExcel, strConn);
                myCommand.Fill(ds, "Table1");
                myCommand.Dispose();
            }
            finally
            {
                if (conn != null
                    && conn.State == ConnectionState.Open)
                {
                    conn.Close();
                    conn.Dispose();
                }
            }

            return ds;
        }

        /// <summary>
        /// 打开窗口
        /// </summary>
        /// <param name="url">url</param>
        /// <param name="target">eg: _blank,_media,_parent,_search,_self,_top</param>
        /// <param name="features">optional.  example, "fullscreen=yes, toolbar=yes"). </param>
        public void OpenWindow(string url, string target, string features)
        {
            string content = string.Format("window.open(\"{0}\",\"{1}\",\"{2}\")", url, target, features);
            RenderScript(null, "", content);
        }

        public void ExportToExcel(Dictionary<string, DataTable[]> forms, string fileName)
        {
            // 下面采用的是DataTable，也可以采用DataSet，其中每个DataTable可以保存成一个 Sheet
            // 迅雷下载时可以在下载完毕后会自动把文件名更新成 xls 或者 xml 的。
            HttpResponse Response = HttpContext.Current.Response;
            Encoding Encoding = Encoding.UTF8;

            Response.ClearContent();
            Response.BufferOutput = true;
            Response.Charset = "utf-8";
            Response.ContentType = "application/ms-excel";
            Response.AddHeader("Content-Transfer-Encoding", "binary");
            Response.ContentEncoding = System.Text.Encoding.UTF8;

            fileName = HttpUtility.UrlEncode(fileName, Encoding);
            StringBuilder builder = new StringBuilder();
            Response.AppendHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");
            builder.Append("<?xml version='1.0'?><?mso-application progid='Excel.Sheet'?>");
            builder.Append(@"<Workbook xmlns='urn:schemas-microsoft-com:office:spreadsheet'
      xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel'
      xmlns:ss='urn:schemas-microsoft-com:office:spreadsheet' xmlns:html='http://www.w3.org/TR/REC-html40'>");
            builder.Append(@"<DocumentProperties xmlns='urn:schemas-microsoft-com:office:office'>");
            builder.Append(@"<Author>DMS</Author><LastAuthor>DMS</LastAuthor>
          <Company>GZ-GMCC</Company><Version>1990</Version>");
            builder.Append("</DocumentProperties>");
            builder.Append(@"<Styles><Style ss:ID='Default' ss:Name='Normal'><Alignment ss:Vertical='Center'/>
      <Borders/><Font ss:FontName='宋体' x:CharSet='134' ss:Size='12'/><Interior/><NumberFormat ss:Format='@'/><Protection/></Style>");
            //定义标题样式    
            builder.Append(@"<Style ss:ID='Title'><Alignment ss:Horizontal='Center' ss:Vertical='Center'/>
       <Font ss:FontName='宋体' x:CharSet='134' ss:Size='14' ss:Color='#000000' ss:Bold='1'/></Style>");
            //定义统计信息样式    
            builder.Append(@"<Style ss:ID='StatisticInfo'>
       <Font ss:FontName='宋体' x:CharSet='134' ss:Size='12' ss:Color='#000000' ss:Bold='1'/></Style>");
            //定义表头样式   
            builder.Append(@"<Style ss:ID='Header'><Borders><Border ss:Position='Bottom' ss:LineStyle='Continuous' ss:Weight='1'/>
       <Border ss:Position='Left' ss:LineStyle='Continuous' ss:Weight='1'/>
       <Border ss:Position='Right' ss:LineStyle='Continuous' ss:Weight='1'/>
       <Border ss:Position='Top' ss:LineStyle='Continuous' ss:Weight='1'/></Borders><Alignment ss:Horizontal='Center' ss:Vertical='Center'/>
       <Font ss:FontName='宋体' x:CharSet='134' ss:Size='12' ss:Color='#000000' ss:Bold='1'/></Style>");

            //定义边框
            builder.Append(@"<Style ss:ID='border'><NumberFormat ss:Format='@'/><Borders>
      <Border ss:Position='Bottom' ss:LineStyle='Continuous' ss:Weight='1'/>
      <Border ss:Position='Left' ss:LineStyle='Continuous' ss:Weight='1'/>
      <Border ss:Position='Right' ss:LineStyle='Continuous' ss:Weight='1'/>
      <Border ss:Position='Top' ss:LineStyle='Continuous' ss:Weight='1'/></Borders></Style>");
            builder.Append(@"<Style ss:ID='borderNumber'><NumberFormat ss:Format='0_ '/><Borders>
      <Border ss:Position='Bottom' ss:LineStyle='Continuous' ss:Weight='1'/>
      <Border ss:Position='Left' ss:LineStyle='Continuous' ss:Weight='1'/>
      <Border ss:Position='Right' ss:LineStyle='Continuous' ss:Weight='1'/>
      <Border ss:Position='Top' ss:LineStyle='Continuous' ss:Weight='1'/></Borders></Style>");
            DataTable[] dts;
            string title;
            builder.Append("</Styles>");
            int rowCount = 0;
            foreach (KeyValuePair<string, DataTable[]> pair in forms)
            {
                dts = pair.Value;
                title = pair.Key;
                builder.Append("<Worksheet ss:Name='" + title + "'>");
                string merge = "";
                builder.Append("<Table x:FullColumns='1' x:FullRows='1'>");
                for (int i = 0; i < dts.Length; i++)
                {
                    DataTable dt = dts[i];
                    //Sheet 中的数据起始行和结束行。
                    int start = 0;
                    int end = dt.Rows.Count;

                    if (i == 0)
                        merge = "ss:MergeAcross='0'";
                    else
                        merge = "";

                    //输出标题
                    if (i > 0)
                    {//特殊处理，第一个datatable不输出标题（入库和出库单基本信息）
                        builder.Append("\r\n<Row ss:AutoFitHeight='1'>");
                        builder.Append("<Cell ss:StyleID='Title' ss:MergeAcross='" + (dt.Columns.Count - 1) + "'><Data ss:Type='String'>" + dt.TableName + "</Data></Cell>");
                        builder.Append("\r\n</Row>");
                    }

                    ////输出表头
                    //builder.Append("\r\n<Row ss:AutoFitHeight='1'>");
                    //if (i > 0)
                    //{
                    //    for (int j = 0; j < dt.Columns.Count; j++)
                    //    {
                    //        builder.Append(String.Format("<Cell ss:StyleID='Header' {0}><Data ss:Type='String'>", merge) + dt.Columns[j].ColumnName + "</Data></Cell>");
                    //    }
                    //}
                    //builder.Append("\r\n</Row>");


                    for (int j = start; j < end; j++)
                    {
                        builder.Append("<Row ss:AutoFitWeight='1'>");
                        for (int c = 0; c < dt.Columns.Count; c++)
                        {
                            string dataType = "String";
                            string styleID = "border";
                            int t;
                            float tf;
                            if (int.TryParse(dt.Rows[j][c].ToString(), out t) ||
                                float.TryParse(dt.Rows[j][c].ToString(), out tf))
                            {
                                dataType = "Number";
                                styleID = "borderNumber";
                            }
                            builder.Append(
                                String.Format("<Cell ss:StyleID='{2}' {0}><Data ss:Type='{1}'>", merge, dataType,
                                              styleID) +
                                System.Security.SecurityElement.Escape(dt.Rows[j][c].ToString()) + "</Data></Cell>");
                        }

                        builder.Append("</Row>");
                        //行计数
                        rowCount++;
                        //每1000行数据输出一次，防止内存溢出
                        if(rowCount%1000==0)
                        {
                            Response.Write(builder.ToString());
                            builder.Clear();
                        }
                    }
                    //Response.Flush();
                }
                builder.Append("</Table>");
                builder.Append("</Worksheet>");
            }
            builder.Append("</Workbook>");
            //System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
            //doc.LoadXml(builder.ToString());
            //System.IO.StringWriter sw = new System.IO.StringWriter();
            //using (System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(sw))
            //{
            //    writer.Indentation = 2;  // the Indentation
            //    writer.Formatting = System.Xml.Formatting.Indented;
            //    doc.WriteContentTo(writer);
            //    writer.Close();
            //}

            //Response.Write(sw.ToString());
            //输出剩余数据
            Response.Write(builder.ToString());
            builder.Clear();
            Response.End();
        }
    }
}
